const OSS = require('ali-oss');
const { STS } = require('ali-oss');
const { setCache, getCache } = require('../../cache');
const client = new OSS({
    cname: true,//支持使用自定义域名访问OSS
    endpoint: 'http://static.bigkel.com', //自定义域名
    // 从环境变量中获取访问凭证。运行本代码示例之前，请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    // accessKeyId: "LTAI5tLjcwZQRWbd7duLotwo",
    // accessKeySecret: "GcRJyGSJbbmmxnDfY1c168mJmbfsSE",
    accessKeyId: "LTAI5tRodCstLAn54w5EyobQ",
    accessKeySecret: "2v3JpXqz9NpSZHBvLrG9WyDVEzrN3o",
    // yourRegion填写Bucket所在地域。以华东1（杭州）为例，Region填写为oss-cn-hangzhou。
    region: 'oss-cn-shenzhen',
    authorizationV4: true,
    // yourBucketName填写Bucket名称。
    bucket: "bigkel-com",
});

//使用map缓存临时凭证


//获取sts临时凭证
async function getSTStoken() {
    try {
        const key = 'stsToken'; // 缓存键名
        const cachedToken = getCache(key);

        if (cachedToken) {
            console.log('使用缓存中的凭证');
            return cachedToken; // 返回缓存中的凭证
        }

        const sts = new STS({
            // accessKeyId: process.env.OSS_ACCESS_KEY_ID,
            // accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET
            accessKeyId: "LTAI5tRodCstLAn54w5EyobQ",
            accessKeySecret: "2v3JpXqz9NpSZHBvLrG9WyDVEzrN3o",
        });
        const res = await sts.assumeRole('acs:ram::1244592409053276:role/ramosstest', '', '3600', 'sessiontest');
        setCache(
            key,
            {
                bucket: "bigkel-com",
                region: 'oss-cn-shenzhen',
                ...res.credentials
            },
            res.credentials.Expiration - Math.floor(Date.now() / 1000)
        ); // 设置缓存
        return {
            bucket: "bigkel-com",
            region: 'oss-cn-shenzhen',
            ...res.credentials
        };
    } catch (error) {
        console.log("临时凭证获取失败：\n", error);
        return error;
    }


}


//列举存储空间
async function listBuckets() {
    try {
        // 列举当前账号所有地域下的存储空间。
        const result = await client.listBuckets();
        return result.buckets;
    } catch (err) {
    }
}


//创建存储空间函数
const putBucket = async ({ storageClass = "Standard", acl = "private", dataRedundancyType = "LRS", bucket }) => {
    try {
        const options = {
            storageClass: storageClass, // 存储空间的默认存储类型为标准存储，即Standard。如果需要设置存储空间的存储类型为归档存储，请替换为Archive。
            acl: acl, // 存储空间的默认读写权限为私有，即private。如果需要设置存储空间的读写权限为公共读，请替换为public-read。
            dataRedundancyType: dataRedundancyType // 存储空间的默认数据容灾类型为本地冗余存储，即LRS。如果需要设置数据容灾类型为同城冗余存储，请替换为ZRS。
        }
        // 填写Bucket名称。
        const result = await client.putBucket(bucket, options);
        console.log("存储空间创建成功：", result);
        return result;
    } catch (error) {
        console.log("存储空间创建失败：", error);
        return error;
    }
}

//提取name="/"为后缀的object并组织成树
const getObjectToDirTree = (objectList) => {

    let dirList = [];
    objectList.forEach(item => {
        //如果item.name以"/"结尾，则为目录
        if (item.name.endsWith("/")) {
            dirList.push(item);
        }
    })
    // console.log("遍历 结果：", dirList)
    //将dirList转换为树状结构
    dirList = dirList.map(item => {
        console.log("遍历dirList id:", item.name.split('/'))
        return {
            ...item,
            key: item.name,
            id: item.name.split('/')[item.name.split('/').length - 2],
            title: item.name.split('/')[item.name.split('/').length - 2] || "/",
            prentId: item.name.split('/')[item.name.split('/').length - 3] || "/"
        }
    })
    // 递归生成树状结构
    console.log("处理结果：", dirList)
    const getList = (array, prentId) => {
        let list = []
        // 除去prentId节点不相等的剩余节点
        const arr = array.filter((item, index) => {
            if (item.prentId !== prentId) {
                return {
                    ...item,
                    key: index
                }
            }
        })
        array.forEach((item, i) => {
            if (item.prentId === prentId) {
                list.push({
                    ...item,
                    // key: `${item.key}-${i}`,
                    children: getList(arr, item.id)
                })
            }
        })
        return list;
    }
    const dirTree = getList(dirList, "images");


    return dirTree;
}

//分页查看文件列表
async function listFiles({ prefix, nextContinuationToken = null, maxKeys }) {
    try {
        const result = await client.listV2({
            'prefix': prefix ? prefix : "images/",        // 前缀匹配，默认为空字符串
            'max-keys': maxKeys,  // 每页数量（最大1000）
            'continuation-token': nextContinuationToken        // 分页标识
        });
        return {
            nextContinuationToken: result.nextContinuationToken, // 下一页标识（新版API）
            prefixes: result.prefixes,
            isTruncated: result.isTruncated,  // 是否还有更多结果
            pageSize: result.keyCount,
            list: result.objects.filter(obj => { return obj.name.endsWith('/') == false }),
            objects: result.objects.map(obj => ({
                name: obj.name,
                url: obj.url,         // 文件名
                lastModified: obj.lastModified, // 最后修改时间
                etag: obj.etag,         // 文件哈希值
                size: obj.size          // 文件大小（字节）
            })),
            // dirTree: getObjectToDirTree(result.objects)
        };
    } catch (error) {
        return null;
    }
}


//获取目录
async function listAllSubdirectories({ dir, delimiter }) {
    try {
        let subdirectories = [];
        let stack = [dir]; // 使用栈保存待处理的目录

        while (stack.length > 0) {
            const currentDir = stack.pop();
            const result = await client.list({
                prefix: currentDir,
                delimiter: '/'
            });

            if (result.prefixes) {
                result.prefixes.forEach(subDir => {
                    subdirectories.push(subDir);
                    stack.push(subDir); // 将子目录加入栈
                });
            }
        }

        // return subdirectories;
        let list = subdirectories.map(item => {
            return {
                name: item,
                key: item
            }
        })

        const dirTree = getObjectToDirTree(list)
        return dirTree;

    } catch (error) {
        console.error('获取目录失败:', error);
        return null;
    }
}

//删除目录
async function deleteDirectory({ prefix }) {
    try {
        let result = await client.list({ prefix });
        const objects = result.objects || [];
        await Promise.all(objects.map(obj => client.delete(obj.name)));
        console.log('目录删除成功');
        return {
            code: 0,
            msg: "删除成功",
        }
        // console.log(`Directory ${prefix} and all its contents have been deleted.`);
    } catch (error) {
        // console.error('目录删除失败：\n', error);
        return {
            code: 1,
            msg: "删除失败",
            error: error.message
        }
    }
}

//新建目录
async function createDirectory({ dirName, parentDir }) {
    try {
        await client.put(`${parentDir}${dirName}/`, new Buffer(''));
        console.log('目录创建成功');
        return {
            code: 0,
            msg: "创建成功"
        }
    } catch (error) {
        console.error('目录创建失败:', error);
        return {
            code: 1,
            msg: "创建失败",
            error: error.message
        }
    }
}






// 删除单个Object
async function deleteObject({ name }) {
    try {
        // 填写Object完整路径。Object完整路径中不能包含Bucket名称。
        const result = await client.delete(name);
        // console.log("删除成功：\n", result);
        // ctx.boxy = res;
        return result;
    } catch (error) {
        console.error("删除失败：\n", error);
        ctx.body = error;
    }
}




module.exports = {

    putBucket,
    listBuckets,
    listFiles,
    listAllSubdirectories,
    deleteDirectory,
    deleteObject,
    createDirectory,
    getSTStoken
}